﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;

namespace 对象拷贝
{
    class Program
    {
        static void Main(string[] args)
        {
            #region 浅拷贝
            A a = new A(34);
            B b = new B("张三");

            C c = new C(a, b);
            C c2 = (C)c.Clone();

            Console.WriteLine("拷贝之前，结构成员的字段值为{0}，引用类型成员的字段值为{1}", c.b.name, c.a.id);
            Console.WriteLine("拷贝之后，新的结构成员的字段值为{0}，引用类型成员的字段值为{1}", c2.b.name, c2.a.id);

            c.a.id = 100;
            c.b.name = "王麻子";

            Console.WriteLine("拷贝之前，结构成员的字段值为{0}，引用类型成员的字段值为{1}", c.b.name, c.a.id);
            Console.WriteLine("拷贝之后，新的结构成员的字段值为{0}，引用类型成员的字段值为{1}", c2.b.name, c2.a.id);

            #endregion

            Console.WriteLine("--------------------------深拷贝---------------------------");
            A1 a1 = new A1(60);
            B1 b1 = new B1("家园防线");
            C1 c3 = new C1(a1, b1);
            C1 c4 = (C1)c3.Clone1();
            Console.WriteLine("拷贝之前，结构成员的字段值为{0}，引用类型成员的字段值为{1}", c3.b.name,c3.a.id);

            Console.WriteLine("拷贝之后，新的结构成员的字段值为{0}，引用类型成员的字段值为{1}", c4.b.name,c4.a.id);

            //修改拷贝之前引用类型的字段值
            c3.b.name = "极品飞车";
            c3.a.id = 80;

            Console.WriteLine("修改之后，结构成员的字段值为{0}，引用类型成员的字段值为{1}", c3.b.name, c3.a.id);
            Console.WriteLine("修改之后，新的结构成员的字段值为{0}，引用类型成员的字段值为{1}", c4.b.name, c4.a.id);




            Console.ReadKey();

        }
    }

    class A
    {
        public int id;
        public A(int id)
        {
            this.id = id;
        }
    }

    struct B
    {
        public string name;
        public B(string name)
        {
            this.name = name;
        }
    }
    class C
    {
        public A a;
        public B b;
        public C(A a, B b)
        {
            this.a = a;
            this.b = b;
        }

        public object Clone()
        {
            return MemberwiseClone(); //对引用类型实施浅复制
        }


    }

    //采用序列化和反序列化深拷贝，但必须把所有的类打上[Serializable]
    [Serializable]
    class A1
    {
        public int id;
        public A1()
        {

        }

        public A1(int id)
        {
            this.id = id;
        }
    }
    [Serializable]
    struct B1
    {
        public string name;
        public B1(string name)
        {
            this.name = name;
        }
    }
    [Serializable]
    class C1
    {
        public A1 a;
        public B1 b;
        public C1(A1 a, B1 b)
        {
            this.a = a;
            this.b = b;
        }
        //深拷贝 对每个对象成员进行复制
        public object Clone()
        {
            A1 a1 = new A1();
            a1.id = this.a.id;

            B1 b1 = this.b; //值类型直接赋值

            C1 c1 = new C1(a1,b1);

            return c1;
        }

        //使用序列化和反序列化进行复制
        public object Clone1()
        {
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream ms = new MemoryStream();
            bf.Serialize(ms, this); //复制到流中
            ms.Position = 0;
            return (bf.Deserialize(ms));
        }


    }



}
